home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / barstat.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  19.2 KB  |  773 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  13.  
  14. #ifdef AFX_CORE3_SEG
  15. #pragma code_seg(AFX_CORE3_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. #define new DEBUG_NEW
  24.  
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CStatusBar creation, etc
  27.  
  28. #define SBPF_UPDATE 0x0001  // pending update of text
  29.  
  30. struct AFX_STATUSPANE
  31. {
  32.     UINT    nID;        // IDC of indicator: 0 => normal text area
  33.     int     cxText;     // width of string area in pixels
  34.                         //   on both sides there is a 3 pixel gap and
  35.                         //   a one pixel border, making a pane 6 pixels wider
  36.     UINT    nStyle;     // style flags (SBPS_*)
  37.     UINT    nFlags;     // state flags (SBPF_*)
  38.     CString strText;    // text in the pane
  39. };
  40.  
  41. inline AFX_STATUSPANE* CStatusBar::_GetPanePtr(int nIndex) const
  42. {
  43.     ASSERT((nIndex >= 0 && nIndex < m_nCount) || m_nCount == 0);
  44.     return ((AFX_STATUSPANE*)m_pData) + nIndex;
  45. }
  46.  
  47. #ifdef AFX_INIT_SEG
  48. #pragma code_seg(AFX_INIT_SEG)
  49. #endif
  50.  
  51. #define CX_PANE_BORDER 6    // 3 pixels on each side of each pane
  52.  
  53. CStatusBar::CStatusBar()
  54. {
  55.     // setup default border/margin depending on type of system
  56.     m_cyTopBorder = 2;
  57.     if (afxData.bWin4)
  58.     {
  59.         m_cxLeftBorder = 0;
  60.         m_cxRightBorder = 0;
  61.         m_cyBottomBorder = 0;
  62.     }
  63.     else
  64.     {
  65.         m_cxLeftBorder = 2;
  66.         m_cxRightBorder = 2;
  67.         m_cyBottomBorder = 1;
  68.     }
  69.     // minimum height set with SB_SETMINHEIGHT is cached
  70.     m_nMinHeight = 0;
  71. }
  72.  
  73. CStatusBar::~CStatusBar()
  74. {
  75.     AllocElements(0, 0);    // destroys existing elements
  76. }
  77.  
  78. BOOL CStatusBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
  79. {
  80.     return CreateEx(pParentWnd, 0, dwStyle, nID);
  81. }
  82.  
  83. BOOL CStatusBar::CreateEx(CWnd* pParentWnd, DWORD dwCtrlStyle, DWORD dwStyle, UINT nID)
  84. {
  85.     ASSERT_VALID(pParentWnd);   // must have a parent
  86.  
  87.     // save the style (some of these style bits are MFC specific)
  88.     m_dwStyle = (dwStyle & CBRS_ALL);
  89.  
  90.     // translate MFC style bits to windows style bits
  91.     dwStyle &= ~CBRS_ALL;
  92.     dwStyle |= CCS_NOPARENTALIGN|CCS_NOMOVEY|CCS_NODIVIDER|CCS_NORESIZE;
  93. #if !defined(_WIN32_WCE)
  94.     if (pParentWnd->GetStyle() & WS_THICKFRAME)
  95.         dwStyle |= SBARS_SIZEGRIP;
  96. #endif // _WIN32_WCE
  97.     dwStyle |= dwCtrlStyle;
  98.  
  99.     // initialize common controls
  100.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_BAR_REG));
  101.  
  102.     // create the HWND
  103.     CRect rect; rect.SetRectEmpty();
  104.     return CWnd::Create(STATUSCLASSNAME, NULL, dwStyle, rect, pParentWnd, nID);
  105. }
  106.  
  107. BOOL CStatusBar::PreCreateWindow(CREATESTRUCT& cs)
  108. {
  109.     // in Win4, status bars do not have a border at all, since it is
  110.     //  provided by the client area.
  111.     if (afxData.bWin4 &&
  112.         (m_dwStyle & (CBRS_ALIGN_ANY|CBRS_BORDER_ANY)) == CBRS_BOTTOM)
  113.     {
  114.         m_dwStyle &= ~(CBRS_BORDER_ANY|CBRS_BORDER_3D);
  115.     }
  116.     return CControlBar::PreCreateWindow(cs);
  117. }
  118.  
  119. BOOL CStatusBar::SetIndicators(const UINT* lpIDArray, int nIDCount)
  120. {
  121.     ASSERT_VALID(this);
  122.     ASSERT(nIDCount >= 1);  // must be at least one of them
  123.     ASSERT(lpIDArray == NULL ||
  124.         AfxIsValidAddress(lpIDArray, sizeof(UINT) * nIDCount, FALSE));
  125.     ASSERT(::IsWindow(m_hWnd));
  126.  
  127.     // first allocate array for panes and copy initial data
  128.     if (!AllocElements(nIDCount, sizeof(AFX_STATUSPANE)))
  129.         return FALSE;
  130.     ASSERT(nIDCount == m_nCount);
  131.  
  132.     // copy initial data from indicator array
  133.     BOOL bResult = TRUE;
  134.     if (lpIDArray != NULL)
  135.     {
  136.         HFONT hFont = (HFONT)SendMessage(WM_GETFONT);
  137.         CClientDC dcScreen(NULL);
  138.         HGDIOBJ hOldFont = NULL;
  139.         if (hFont != NULL)
  140.             hOldFont = dcScreen.SelectObject(hFont);
  141.  
  142.         AFX_STATUSPANE* pSBP = _GetPanePtr(0);
  143.         for (int i = 0; i < nIDCount; i++)
  144.         {
  145.             pSBP->nID = *lpIDArray++;
  146.             pSBP->nFlags |= SBPF_UPDATE;
  147.             if (pSBP->nID != 0)
  148.             {
  149.                 if (!pSBP->strText.LoadString(pSBP->nID))
  150.                 {
  151.                     TRACE1("Warning: failed to load indicator string 0x%04X.\n",
  152.                         pSBP->nID);
  153.                     bResult = FALSE;
  154.                     break;
  155.                 }
  156.                 pSBP->cxText = dcScreen.GetTextExtent(pSBP->strText).cx;
  157.                 ASSERT(pSBP->cxText >= 0);
  158.                 if (!SetPaneText(i, pSBP->strText, FALSE))
  159.                 {
  160.                     bResult = FALSE;
  161.                     break;
  162.                 }
  163.             }
  164.             else
  165.             {
  166.                 // no indicator (must access via index)
  167.                 // default to 1/4 the screen width (first pane is stretchy)
  168.                 pSBP->cxText = ::GetSystemMetrics(SM_CXSCREEN)/4;
  169.                 if (i == 0)
  170.                     pSBP->nStyle |= (SBPS_STRETCH | SBPS_NOBORDERS);
  171.             }
  172.             ++pSBP;
  173.         }
  174.         if (hOldFont != NULL)
  175.             dcScreen.SelectObject(hOldFont);
  176.     }
  177.     UpdateAllPanes(TRUE, TRUE);
  178.  
  179.     return bResult;
  180. }
  181.  
  182. BOOL CStatusBar::AllocElements(int nElements, int cbElement)
  183. {
  184.     // destruct old elements
  185.     AFX_STATUSPANE* pSBP = _GetPanePtr(0);
  186.     for (int i = 0; i < m_nCount; i++)
  187.     {
  188.         pSBP->strText.~CString();
  189.         ++pSBP;
  190.     }
  191.  
  192.     // allocate new elements
  193.     if (!CControlBar::AllocElements(nElements, cbElement))
  194.         return FALSE;
  195.  
  196.     // construct new elements
  197.     pSBP = _GetPanePtr(0);
  198.     for (i = 0; i < m_nCount; i++)
  199.     {
  200.         memcpy(&pSBP->strText, &afxEmptyString, sizeof(CString));
  201.         ++pSBP;
  202.     }
  203.     return TRUE;
  204. }
  205.  
  206. void CStatusBar::CalcInsideRect(CRect& rect, BOOL bHorz) const
  207. {
  208.     ASSERT_VALID(this);
  209.     ASSERT(::IsWindow(m_hWnd));
  210.     ASSERT(bHorz);  // vertical status bar not supported
  211.  
  212.     // subtract standard CControlBar borders
  213.     CControlBar::CalcInsideRect(rect, bHorz);
  214.  
  215. #if !defined(_WIN32_WCE)
  216.     // subtract size grip if present
  217.     if ((GetStyle() & SBARS_SIZEGRIP) && !::IsZoomed(::GetParent(m_hWnd)))
  218.     {
  219.         // get border metrics from common control
  220.         int rgBorders[3];
  221.         CStatusBar* pBar = (CStatusBar*)this;
  222.         pBar->DefWindowProc(SB_GETBORDERS, 0, (LPARAM)&rgBorders);
  223.  
  224.         // size grip uses a border + size of scrollbar + cx border
  225.         rect.right -= rgBorders[0] + ::GetSystemMetrics(SM_CXVSCROLL) +
  226.             ::GetSystemMetrics(SM_CXBORDER) * 2;
  227.     }
  228. #endif // _WIN32_WCE
  229. }
  230.  
  231. void CStatusBar::UpdateAllPanes(BOOL bUpdateRects, BOOL bUpdateText)
  232. {
  233.     ASSERT_VALID(this);
  234.     ASSERT(::IsWindow(m_hWnd));
  235.  
  236.     // update the status pane locations
  237.     if (bUpdateRects)
  238.     {
  239.         // get border information and client work area
  240.         CRect rect; GetWindowRect(rect);
  241.         rect.OffsetRect(-rect.left, -rect.top);
  242.         CalcInsideRect(rect, TRUE);
  243.         int rgBorders[3];
  244.         VERIFY((BOOL)DefWindowProc(SB_GETBORDERS, 0, (LPARAM)&rgBorders));
  245.  
  246.         // determine extra space for stretchy pane
  247.         int cxExtra = rect.Width() + rgBorders[2];
  248.         int nStretchyCount = 0;
  249.         AFX_STATUSPANE* pSBP = _GetPanePtr(0);
  250.         for (int i = 0; i < m_nCount; i++)
  251.         {
  252.             if (pSBP->nStyle & SBPS_STRETCH)
  253.                 ++nStretchyCount;
  254.             cxExtra -= (pSBP->cxText+CX_PANE_BORDER + rgBorders[2]);
  255.             ++pSBP;
  256.         }
  257.  
  258.         // determine right edge of each pane
  259.         int* rgRights = (int*)_alloca(m_nCount * sizeof(int));
  260.         int right = rgBorders[0];
  261.         pSBP = _GetPanePtr(0);
  262.         for (i = 0; i < m_nCount; i++)
  263.         {
  264.             // determine size of the pane
  265.             ASSERT(pSBP->cxText >= 0);
  266.             right += pSBP->cxText+CX_PANE_BORDER;
  267.             if ((pSBP->nStyle & SBPS_STRETCH) && cxExtra > 0)
  268.             {
  269.                 ASSERT(nStretchyCount != 0);
  270.                 int cxAddExtra = cxExtra / nStretchyCount;
  271.                 right += cxAddExtra;
  272.                 --nStretchyCount;
  273.                 cxExtra -= cxAddExtra;
  274.             }
  275.             rgRights[i] = right;
  276.  
  277.             // next pane
  278.             ++pSBP;
  279.             right += rgBorders[2];
  280.         }
  281.  
  282.         // set new right edges for all panes
  283.         DefWindowProc(SB_SETPARTS, m_nCount, (LPARAM)rgRights);
  284.     }
  285.  
  286.     // update text in the status panes if specified
  287.     if (bUpdateText)
  288.     {
  289.         AFX_STATUSPANE* pSBP = _GetPanePtr(0);
  290.         for (int i = 0; i < m_nCount; i++)
  291.         {
  292.             if (pSBP->nFlags & SBPF_UPDATE)
  293.                 SetPaneText(i, pSBP->strText);
  294.             ++pSBP;
  295.         }
  296.     }
  297. }
  298.  
  299. #ifdef AFX_CORE3_SEG
  300. #pragma code_seg(AFX_CORE3_SEG)
  301. #endif
  302.  
  303. /////////////////////////////////////////////////////////////////////////////
  304. // CStatusBar attribute access
  305.  
  306. int CStatusBar::CommandToIndex(UINT nIDFind) const
  307. {
  308.     ASSERT_VALID(this);
  309.  
  310.     if (m_nCount <= 0)
  311.         return -1;
  312.  
  313.     AFX_STATUSPANE* pSBP = _GetPanePtr(0);
  314.     for (int i = 0; i < m_nCount; i++, pSBP++)
  315.         if (pSBP->nID == nIDFind)
  316.             return i;
  317.  
  318.     return -1;
  319. }
  320.  
  321. UINT CStatusBar::GetItemID(int nIndex) const
  322. {
  323.     ASSERT_VALID(this);
  324.     return _GetPanePtr(nIndex)->nID;
  325. }
  326.  
  327. void CStatusBar::GetItemRect(int nIndex, LPRECT lpRect) const
  328. {
  329.     ASSERT_VALID(this);
  330.     ASSERT(::IsWindow(m_hWnd));
  331.  
  332.     CStatusBar* pBar = (CStatusBar*)this;
  333.     if (!pBar->DefWindowProc(SB_GETRECT, nIndex, (LPARAM)lpRect))
  334.         ::SetRectEmpty(lpRect);
  335. }
  336.  
  337. UINT CStatusBar::GetPaneStyle(int nIndex) const
  338. {
  339.     return _GetPanePtr(nIndex)->nStyle;
  340. }
  341.  
  342. void CStatusBar::SetPaneStyle(int nIndex, UINT nStyle)
  343. {
  344.     AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  345.     if (pSBP->nStyle != nStyle)
  346.     {
  347.         // if the pane is changing SBPS_STRETCH, then...
  348.         if ((pSBP->nStyle ^ nStyle) & SBPS_STRETCH)
  349.         {
  350.             // ... we need to re-layout the panes
  351.             pSBP->nStyle = nStyle;
  352.             UpdateAllPanes(TRUE, FALSE);
  353.         }
  354.  
  355.         // use SetPaneText, since it updates the style and text
  356.         pSBP->nStyle = nStyle;
  357.         pSBP->nFlags |= SBPF_UPDATE;
  358.         SetPaneText(nIndex, pSBP->strText);
  359.     }
  360. }
  361.  
  362. void CStatusBar::GetPaneInfo(int nIndex, UINT& nID, UINT& nStyle,
  363.     int& cxWidth) const
  364. {
  365.     ASSERT_VALID(this);
  366.  
  367.     AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  368.     nID = pSBP->nID;
  369.     nStyle = pSBP->nStyle;
  370.     cxWidth = pSBP->cxText;
  371. }
  372.  
  373. void CStatusBar::SetPaneInfo(int nIndex, UINT nID, UINT nStyle, int cxWidth)
  374. {
  375.     ASSERT_VALID(this);
  376.  
  377.     BOOL bChanged = FALSE;
  378.     AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  379.     pSBP->nID = nID;
  380.     if (pSBP->nStyle != nStyle)
  381.     {
  382.         if ((pSBP->nStyle ^ nStyle) & SBPS_STRETCH)
  383.             bChanged = TRUE;
  384.         else
  385.         {
  386.             pSBP->nStyle = nStyle;
  387.             pSBP->nFlags |= SBPF_UPDATE;
  388.             SetPaneText(nIndex, pSBP->strText);
  389.         }
  390.         pSBP->nStyle = nStyle;
  391.     }
  392.     if (cxWidth != pSBP->cxText)
  393.     {
  394.         // change width of one pane -> invalidate the entire status bar
  395.         pSBP->cxText = cxWidth;
  396.         bChanged = TRUE;
  397.     }
  398.     if (bChanged)
  399.         UpdateAllPanes(TRUE, FALSE);
  400. }
  401.  
  402. void CStatusBar::GetPaneText(int nIndex, CString& s) const
  403. {
  404.     ASSERT_VALID(this);
  405.  
  406.     AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  407.     s = pSBP->strText;
  408. }
  409.  
  410. CString CStatusBar::GetPaneText(int nIndex) const
  411. {
  412.     ASSERT_VALID(this);
  413.  
  414.     AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  415.     return pSBP->strText;
  416. }
  417.  
  418. BOOL CStatusBar::SetPaneText(int nIndex, LPCTSTR lpszNewText, BOOL bUpdate)
  419. {
  420.     ASSERT_VALID(this);
  421.     ASSERT(::IsWindow(m_hWnd));
  422.  
  423.     AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  424.  
  425.     if (!(pSBP->nFlags & SBPF_UPDATE) &&
  426.         ((lpszNewText == NULL && pSBP->strText.IsEmpty()) ||
  427.          (lpszNewText != NULL && pSBP->strText.Compare(lpszNewText) == 0)))
  428.     {
  429.         // nothing to change
  430.         return TRUE;
  431.     }
  432.  
  433.     TRY
  434.     {
  435.         if (lpszNewText != NULL)
  436.             pSBP->strText = lpszNewText;
  437.         else
  438.             pSBP->strText.Empty();
  439.     }
  440.     CATCH_ALL(e)
  441.     {
  442.         // Note: DELETE_EXCEPTION(e) not required
  443.         return FALSE;
  444.     }
  445.     END_CATCH_ALL
  446.  
  447.     if (!bUpdate)
  448.     {
  449.         // can't update now, wait until later
  450.         pSBP->nFlags |= SBPF_UPDATE;
  451.         return TRUE;
  452.     }
  453.  
  454.     pSBP->nFlags &= ~SBPF_UPDATE;
  455.     DefWindowProc(SB_SETTEXT, ((WORD)pSBP->nStyle)|nIndex,
  456.         (pSBP->nStyle & SBPS_DISABLED) ? NULL :
  457.         (LPARAM)(LPCTSTR)pSBP->strText);
  458.  
  459.     return TRUE;
  460. }
  461.  
  462. /////////////////////////////////////////////////////////////////////////////
  463. // CStatusBar implementation
  464.  
  465. CSize CStatusBar::CalcFixedLayout(BOOL, BOOL bHorz)
  466. {
  467.     ASSERT_VALID(this);
  468.     ASSERT(::IsWindow(m_hWnd));
  469.  
  470.     // determinme size of font being used by the status bar
  471.     TEXTMETRIC tm;
  472.     {
  473.         CClientDC dc(NULL);
  474.         HFONT hFont = (HFONT)SendMessage(WM_GETFONT);
  475.         HGDIOBJ hOldFont = NULL;
  476.         if (hFont != NULL)
  477.             hOldFont = dc.SelectObject(hFont);
  478.         VERIFY(dc.GetTextMetrics(&tm));
  479.         if (hOldFont != NULL)
  480.             dc.SelectObject(hOldFont);
  481.     }
  482.  
  483.     // get border information
  484.     CRect rect; rect.SetRectEmpty();
  485.     CalcInsideRect(rect, bHorz);
  486.     int rgBorders[3];
  487.     DefWindowProc(SB_GETBORDERS, 0, (LPARAM)&rgBorders);
  488.  
  489.     // determine size, including borders
  490.     CSize size;
  491.     size.cx = 32767;
  492.     size.cy = tm.tmHeight - tm.tmInternalLeading - 1
  493.         + rgBorders[1] * 2 + ::GetSystemMetrics(SM_CYBORDER) * 2
  494.         - rect.Height();
  495.     if (size.cy < m_nMinHeight)
  496.         size.cy = m_nMinHeight;
  497.  
  498.     return size;
  499. }
  500.  
  501. /////////////////////////////////////////////////////////////////////////////
  502. // CStatusBar message handlers
  503.  
  504. BEGIN_MESSAGE_MAP(CStatusBar, CControlBar)
  505.     //{{AFX_MSG_MAP(CStatusBar)
  506. WCE_DEL ON_WM_NCHITTEST()
  507. WCE_DEL ON_WM_NCPAINT()
  508.     ON_WM_PAINT()
  509. WCE_DEL ON_WM_NCCALCSIZE()
  510.     ON_WM_SIZE()
  511. WCE_DEL ON_WM_WINDOWPOSCHANGING()
  512.     ON_MESSAGE(WM_SETTEXT, OnSetText)
  513.     ON_MESSAGE(WM_GETTEXT, OnGetText)
  514.     ON_MESSAGE(WM_GETTEXTLENGTH, OnGetTextLength)
  515.     ON_MESSAGE(SB_SETMINHEIGHT, OnSetMinHeight)
  516.     //}}AFX_MSG_MAP
  517. END_MESSAGE_MAP()
  518.  
  519. #if !defined(_WIN32_WCE)
  520. UINT CStatusBar::OnNcHitTest(CPoint)
  521. {
  522.     UINT nResult = (UINT)Default();
  523.     if (nResult == HTBOTTOMRIGHT)
  524.         return HTBOTTOMRIGHT;
  525.     else
  526.         return HTCLIENT;
  527. }
  528.  
  529. void CStatusBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp)
  530. {
  531.     // calculate border space (will add to top/bottom, subtract from right/bottom)
  532.     CRect rect; rect.SetRectEmpty();
  533.     CControlBar::CalcInsideRect(rect, TRUE);
  534.     ASSERT(rect.top >= 2);
  535.  
  536.     // adjust non-client area for border space
  537.     lpncsp->rgrc[0].left += rect.left;
  538.     lpncsp->rgrc[0].top += rect.top - 2;
  539.     lpncsp->rgrc[0].right += rect.right;
  540.     lpncsp->rgrc[0].bottom += rect.bottom;
  541. }
  542. #endif // _WIN32_WCE
  543.  
  544. void CStatusBar::OnBarStyleChange(DWORD dwOldStyle, DWORD dwNewStyle)
  545. {
  546.     if (m_hWnd != NULL &&
  547.         ((dwOldStyle & CBRS_BORDER_ANY) != (dwNewStyle & CBRS_BORDER_ANY)))
  548.     {
  549.         // recalc non-client area when border styles change
  550.         SetWindowPos(NULL, 0, 0, 0, 0,
  551.             SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_DRAWFRAME);
  552.     }
  553. }
  554.  
  555. #if !defined(_WIN32_WCE)
  556. void CStatusBar::OnNcPaint()
  557. {
  558.     EraseNonClient();
  559. }
  560. #endif // _WIN32_WCE
  561.  
  562. // Derived class is responsible for implementing all of these handlers
  563. //  for owner/self draw controls.
  564. void CStatusBar::DrawItem(LPDRAWITEMSTRUCT)
  565. {
  566.     ASSERT(FALSE);
  567. }
  568.  
  569. BOOL CStatusBar::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  570. {
  571.     if (message != WM_DRAWITEM)
  572.         return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  573.  
  574.     ASSERT(pResult == NULL);
  575.     UNUSED(pResult); // unused in release builds
  576.     DrawItem((LPDRAWITEMSTRUCT)lParam);
  577.     return TRUE;
  578. }
  579.  
  580. void CStatusBar::OnPaint()
  581. {
  582.     UpdateAllPanes(FALSE, TRUE);
  583.  
  584.     Default();
  585. }
  586.  
  587. void CStatusBar::OnSize(UINT nType, int cx, int cy)
  588. {
  589.     ASSERT_VALID(this);
  590.     ASSERT(::IsWindow(m_hWnd));
  591.  
  592.     CControlBar::OnSize(nType, cx, cy);
  593.  
  594.     // need to adjust pane right edges (because of stretchy pane)
  595.     UpdateAllPanes(TRUE, FALSE);
  596. }
  597.  
  598. #if !defined(_WIN32_WCE)
  599. void CStatusBar::OnWindowPosChanging(LPWINDOWPOS lpWndPos)
  600. {
  601.     // not necessary to invalidate the borders
  602.     DWORD dwStyle = m_dwStyle;
  603.     m_dwStyle &= ~(CBRS_BORDER_ANY);
  604.     CControlBar::OnWindowPosChanging(lpWndPos);
  605.     m_dwStyle = dwStyle;
  606. }
  607. #endif // _WIN32_WCE
  608.  
  609. LRESULT CStatusBar::OnSetText(WPARAM, LPARAM lParam)
  610. {
  611.     ASSERT_VALID(this);
  612.     ASSERT(::IsWindow(m_hWnd));
  613.  
  614.     int nIndex = CommandToIndex(0);
  615.     if (nIndex < 0)
  616.         return -1;
  617.     return SetPaneText(nIndex, (LPCTSTR)lParam) ? 0 : -1;
  618. }
  619.  
  620. LRESULT CStatusBar::OnGetText(WPARAM wParam, LPARAM lParam)
  621. {
  622.     ASSERT_VALID(this);
  623.     ASSERT(::IsWindow(m_hWnd));
  624.  
  625.     int nMaxLen = (int)wParam;
  626.     if (nMaxLen == 0)
  627.         return 0;       // nothing copied
  628.     LPTSTR lpszDest = (LPTSTR)lParam;
  629.  
  630.     int nLen = 0;
  631.     int nIndex = CommandToIndex(0); // use pane with ID zero
  632.     if (nIndex >= 0)
  633.     {
  634.         AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  635.         nLen = pSBP->strText.GetLength();
  636.         if (nLen > nMaxLen)
  637.             nLen = nMaxLen - 1; // number of characters to copy (less term.)
  638.         memcpy(lpszDest, (LPCTSTR)pSBP->strText, nLen*sizeof(TCHAR));
  639.     }
  640.     lpszDest[nLen] = '\0';
  641.     return nLen+1;      // number of bytes copied
  642. }
  643.  
  644. LRESULT CStatusBar::OnGetTextLength(WPARAM, LPARAM)
  645. {
  646.     ASSERT_VALID(this);
  647.     ASSERT(::IsWindow(m_hWnd));
  648.  
  649.     int nLen = 0;
  650.     int nIndex = CommandToIndex(0); // use pane with ID zero
  651.     if (nIndex >= 0)
  652.     {
  653.         AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  654.         nLen = pSBP->strText.GetLength();
  655.     }
  656.     return nLen;
  657. }
  658.  
  659. LRESULT CStatusBar::OnSetMinHeight(WPARAM wParam, LPARAM)
  660. {
  661.     LRESULT lResult = Default();
  662.     m_nMinHeight = wParam;
  663.     return lResult;
  664. }
  665.  
  666. /////////////////////////////////////////////////////////////////////////////
  667. // CStatusBar idle update through CStatusCmdUI class
  668.  
  669. class CStatusCmdUI : public CCmdUI      // class private to this file!
  670. {
  671. public: // re-implementations only
  672.     virtual void Enable(BOOL bOn);
  673.     virtual void SetCheck(int nCheck);
  674.     virtual void SetText(LPCTSTR lpszText);
  675. };
  676.  
  677. void CStatusCmdUI::Enable(BOOL bOn)
  678. {
  679.     m_bEnableChanged = TRUE;
  680.     CStatusBar* pStatusBar = (CStatusBar*)m_pOther;
  681.     ASSERT(pStatusBar != NULL);
  682.     ASSERT_KINDOF(CStatusBar, pStatusBar);
  683.     ASSERT(m_nIndex < m_nIndexMax);
  684.  
  685.     UINT nNewStyle = pStatusBar->GetPaneStyle(m_nIndex) & ~SBPS_DISABLED;
  686.     if (!bOn)
  687.         nNewStyle |= SBPS_DISABLED;
  688.     pStatusBar->SetPaneStyle(m_nIndex, nNewStyle);
  689. }
  690.  
  691. void CStatusCmdUI::SetCheck(int nCheck) // "checking" will pop out the text
  692. {
  693.     CStatusBar* pStatusBar = (CStatusBar*)m_pOther;
  694.     ASSERT(pStatusBar != NULL);
  695.     ASSERT_KINDOF(CStatusBar, pStatusBar);
  696.     ASSERT(m_nIndex < m_nIndexMax);
  697.  
  698.     UINT nNewStyle = pStatusBar->GetPaneStyle(m_nIndex) & ~SBPS_POPOUT;
  699.     if (nCheck != 0)
  700.         nNewStyle |= SBPS_POPOUT;
  701.     pStatusBar->SetPaneStyle(m_nIndex, nNewStyle);
  702. }
  703.  
  704. void CStatusCmdUI::SetText(LPCTSTR lpszText)
  705. {
  706.     CStatusBar* pStatusBar = (CStatusBar*)m_pOther;
  707.     ASSERT(pStatusBar != NULL);
  708.     ASSERT_KINDOF(CStatusBar, pStatusBar);
  709.     ASSERT(m_nIndex < m_nIndexMax);
  710.  
  711.     pStatusBar->SetPaneText(m_nIndex, lpszText);
  712. }
  713.  
  714. void CStatusBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  715. {
  716.     CStatusCmdUI state;
  717.     state.m_pOther = this;
  718.     state.m_nIndexMax = (UINT)m_nCount;
  719.     for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
  720.         state.m_nIndex++)
  721.     {
  722.         state.m_nID = _GetPanePtr(state.m_nIndex)->nID;
  723.  
  724.         // allow the statusbar itself to have update handlers
  725.         if (CWnd::OnCmdMsg(state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL))
  726.             continue;
  727.  
  728.         // allow target (owner) to handle the remaining updates
  729.         state.DoUpdate(pTarget, FALSE);
  730.     }
  731.  
  732.     // update the dialog controls added to the status bar
  733.     UpdateDialogControls(pTarget, bDisableIfNoHndler);
  734. }
  735.  
  736. /////////////////////////////////////////////////////////////////////////////
  737. // CStatusBar diagnostics
  738.  
  739. #ifdef _DEBUG
  740. void CStatusBar::AssertValid() const
  741. {
  742.     CControlBar::AssertValid();
  743. }
  744.  
  745. void CStatusBar::Dump(CDumpContext& dc) const
  746. {
  747.     CControlBar::Dump(dc);
  748.  
  749.     if (dc.GetDepth() > 0)
  750.     {
  751.         for (int i = 0; i < m_nCount; i++)
  752.         {
  753.             dc << "\nstatus pane[" << i << "] = {";
  754.             dc << "\n\tnID = " << _GetPanePtr(i)->nID;
  755.             dc << "\n\tnStyle = " << _GetPanePtr(i)->nStyle;
  756.             dc << "\n\tcxText = " << _GetPanePtr(i)->cxText;
  757.             dc << "\n\tstrText = " << _GetPanePtr(i)->strText;
  758.             dc << "\n\t}";
  759.         }
  760.     }
  761.     dc << "\n";
  762. }
  763. #endif //_DEBUG
  764.  
  765. #ifdef AFX_INIT_SEG
  766. #pragma code_seg(AFX_INIT_SEG)
  767. #endif
  768.  
  769. IMPLEMENT_DYNAMIC(CStatusBar, CControlBar)
  770.  
  771. /////////////////////////////////////////////////////////////////////////////
  772. #endif // _WIN32_WCE_NO_CONTROLBARS
  773.